<template>
    <div
        class="archive-editor-audio"
        v-loading="loading"
        element-loading-text="拼命加载中..."
        element-loading-spinner="el-icon-loading"
        element-loading-background="#f1f1f2"
    >
        <el-form v-show="opening" class="archive-editor-form" label-position="top" size="mini">
            <el-form-item>
                <draggable
                    :list="resources"
                    @update="resetArchiveResources"
                    v-bind="draggableOptions"
                >
                    <template v-for="(resource, index) in resources">
                        <audioResourceItem
                            :index="index"
                            :key="resource.rid"
                            :resource="resource"
                            @delete="onDeleteFile"
                        />
                    </template>
                </draggable>
                <!-- 上传队列 -->
                <template v-for="(resource, index) in uploadQueue">
                    <audioResourceItem
                        :index="index+resources.length"
                        :key="resource.key"
                        :resource="resource"
                    />
                    <!-- @delete="onDeleteFile" -->
                </template>
                <div class="item-upload-btn upload-image-border el-icon-upload">
                    <input
                        @change="onChangeUploadInput"
                        accept=".mp3, .wav, .ogg"
                        class="item-upload-input"
                        multiple
                        type="file"
                    />
                </div>
            </el-form-item>
            <el-form-item label="合辑封面">
                <coverModule :cover="archiveForm.cover" @change="onChangeCover" />
            </el-form-item>
            <el-form-item label="合辑标题">
                <el-input placeholder="请输入 (建议30字以内)" size="medium" v-model="archiveForm.title" />
            </el-form-item>
            <el-form-item label="合辑分类">
                <el-select placeholder="请选择" v-model="archiveForm.cid">
                    <el-option
                        :key="index"
                        :label="classify.name"
                        :value="classify.cid"
                        v-for="(classify,index) in classifyList"
                    />
                </el-select>
            </el-form-item>
            <el-form-item label="合辑简介 (选填)">
                <el-input
                    :show-word-limit="true"
                    placeholder="有趣的描述更容易被小编推荐为热门动态哦～(=ﾟωﾟ)ﾉ"
                    resize="none"
                    rows="6"
                    type="textarea"
                    v-model="archiveForm.mark"
                />
            </el-form-item>
            <el-form-item>
                <el-button
                    :disabled="canSubmit===false"
                    :type=" canSubmit?'primary':'info' "
                    @click="onClickSubmit"
                    plain
                >提交审核</el-button>
            </el-form-item>
        </el-form>
    </div>
</template>

<script>
import draggable from "vuedraggable";
import generateOSS from "@/utils/uploadHandler";
import defaultSetting from "@/settings";
import {
    archvieAudioCreatorAPI,
    archiveAudioFinderAPI,
    archiveAudioUpdatorAPI,
    audioResourceDestroyerAPI,
    audioClassifyFinderAPI,
} from "@/api/km_archive_audio";
import coverModule from "./components/coverModule.vue";
import audioResourceItem from "./components/audioResourceItem.vue";
import { analysisAudio, computedSign, validateAudioFileMime } from "./utils";

export default {
    components: {
        draggable,
        coverModule,
        audioResourceItem,
    },
    data() {
        return {
            opening: false,
            loading: true,
            classifyList: [
                { cid: 1, name: "未分类" },
                { cid: 2, name: "音游" },
                { cid: 3, name: "奥数魔刃" },
            ],
            archiveForm: {
                cid: 1,
                cover: "",
                title: "",
                mark: "",
                resources: [
                    // 1, 2, 3
                ],
            },
            resources: [
                // { rid: 1, name: "11111", progress: 30 },
                // { rid: 2, name: "222222222", progress: 10 },
                // { rid: 4, name: "", progress: 100 },
            ],
            uploadQueue: [
                // { name: "测试上传队列", progress: 10 }
            ],
            canUpload: true, // 标记上传状态
            draggableOptions: {
                animation: 150, // 拖动排序的动画效果时间
                filter: ".ignore-elements", // 不导致拖拽的选择器(字符串或函数)
                forceFallback: false, // 忽略HTML5的DnD行为，并强制退出。（h5里有个属性也是拖动，这里是为了去掉H5拖动对这个的影响）
            },
        };
    },
    computed: {
        canSubmit() {
            return this.canUpload === true;
        },
        isEditor() {
            return Object.prototype.hasOwnProperty.call(
                this.$route.query,
                "aid"
            );
        },
        archiveID() {
            return this.$route.query.aid;
        },
    },
    created() {
        if (this.isEditor === true) {
            this.editorHandler();
        } else {
            this.loading = false;
            this.opening = true;
        }
        this.getClassify();
    },
    methods: {
        getClassify() {
            audioClassifyFinderAPI().then((res)=> {
                const formatData = res.data.reduce((pv,val)=> {
                    pv.push({
                        cid: val.cid,
                        name: val.name,
                    })
                    return pv;
                },[]);
                this.classifyList = formatData;
            })
        },
        async editorHandler() {
            this.loading = true;
            try {
                const result = await archiveAudioFinderAPI(this.archiveID);
                this.archiveForm = result.data.archive;
                this.resources = result.data.resources;
            } catch (error) {
                this.$message.error("稿件数据获取失败!");
                this.$router.back();
            } finally {
                setTimeout(() => {
                    this.loading = false;
                    this.opening = true;
                }, 300);
            }
        },
        editorSubmitHandler() {
            archiveAudioUpdatorAPI(this.archiveID, this.archiveForm)
                .then((res) => {
                    this.$message.success("修改成功!");
                    this.$router.push({
                        name: "audioArchiveManager",
                    });
                })
                .catch((err) => {
                    this.$message.error("网络错误, 提交修改失败!");
                });
        },
        creatorSubmitHandler() {
            archvieAudioCreatorAPI(this.archiveForm)
                .then((res) => {
                    this.$message.success("发布成功!");
                    this.$router.push({
                        name: "audioArchiveManager",
                    });
                })
                .catch((err) => {
                    this.$message.error("网络错误, 提交稿件失败!");
                });
        },
        resetArchiveResources() {
            this.archiveForm.resources = this.resources.reduce((pv, val) => {
                pv.push(val.rid);
                return pv;
            }, []);
        },
        onChangeCover(object) {
            this.archiveForm.cover = object;
        },
        onClickSubmit() {
            if (this.isEditor === false) {
                this.creatorSubmitHandler();
            } else {
                this.editorSubmitHandler();
            }
        },
        onDeleteFile(index) {
            const resource = this.resources[index];
            this.$confirm("此操作将永久删除该文件, 是否继续?", "删除文件", {
                confirmButtonText: "确认删除",
                cancelButtonText: "取消",
                type: "warning",
            })
                .then((res) => {
                    return audioResourceDestroyerAPI(resource.rid);
                })
                .then((res) => {
                    this.resources.splice(index, 1);
                    this.resetArchiveResources();
                    this.$message.success("删除成功!");
                })
                .catch((error) => {
                    if (error === cancel) {
                        this.$message.info("已取消删除!");
                    } else {
                        this.$message.error("网络错误,删除失败!");
                    }
                });
        },
        onChangeUploadInput(evt) {
            const files = [...evt.target.files];
            // eslint-disable-next-line no-param-reassign
            evt.target.value = "";
            // console.log(files);
            files.forEach((file) => {
                // console.log(file);
                if (validateAudioFileMime(file)) {
                    this.uploadQueue.push({
                        key: Math.random() * 50,
                        file,
                        name: file.name,
                        size: file.size,
                        progress: 0,
                    });
                }
            });
            if (this.canUpload === true) {
                this.uploadHandler();
            }
        },
        // 上传操作
        async uploadHandler() {
            this.canUpload = false;

            const task = this.uploadQueue[0];
            // console.log(task);
            const sign = computedSign(task.file); // 获得签名
            const { duration } = await analysisAudio(task.file); // 解析音频数据, 获取音频时长
            const client = await generateOSS(); // 获取oss实例

            this.$set(task, "duration", duration);

            try {
                const result = await client.multipartUpload(
                    `resources/audio/${sign}`,
                    task.file,
                    {
                        // 进行实际的上传操作
                        progress: (val) => {
                            task.progress = Math.floor(val * 10000) / 100;
                        },
                        headers: {
                            "x-oss-tagging": "delete=1",
                        },
                        callback: {
                            url: `${defaultSetting.host}/x/v1/resource/audio/uploader`,
                            body:
                                // eslint-disable-next-line no-template-curly-in-string
                                "bucket=${bucket}&object=${object}&size=${size}&mimeType=${mimeType}" +
                                `&name=${task.name}&cover=${this.archiveForm.cover}`,
                        },
                    }
                );
                // console.log(result);
                this.$set(task, "rid", result.data.rid);
                this.resources.push(task);
                // 这里重新编辑一下资源
                this.resetArchiveResources();
                this.uploadQueue.shift();
            } catch (error) {
                if (error.name === "cancel") {
                    this.$message.error("上传已取消");
                }
            } finally {
                // 如果上传队列还有资源, 则递归上传
                if (this.uploadQueue.length > 0) {
                    this.uploadHandler();
                } else {
                    this.canUpload = true;
                    this.$message({
                        type: "success",
                        message: "已完成上传任务",
                    });
                }
            }
        },
    },
};
</script>

<style lang="scss" scoped>
.archive-editor-audio {
    min-height: calc(100vh - 50px);
    
    .archive-editor-form {
        min-height: calc(100vh - 50px);
        padding: 20px;
        box-sizing: border-box;
        background-color: #fff;
    }

    .item-upload-btn {
        width: 100%;
        height: 40px;
        position: relative;
        display: flex;
        align-items: center;
        justify-content: center;
        font-size: 18px;
        color: #999;
        cursor: pointer;

        &::after {
            content: "上传";
            margin-left: 5px;
            font-size: 12px;
        }

        .item-upload-input {
            width: 100%;
            height: 100%;
            position: absolute;
            z-index: 3;
            display: block;
            opacity: 0;
            cursor: pointer;
        }
    }
}
</style>
